package net.oschina.simpleplus.tcp;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.oschina.simpleplus.cnf.GlobalConfig;
import net.oschina.simpleplus.cnf.NettyUtil;
import net.oschina.simpleplus.core.SnowFlake;

public class PacketHandler extends SimpleChannelInboundHandler<Packet> {
	
	private static final Logger logger = LoggerFactory.getLogger(PacketHandler.class);
	
	private SnowFlake snowFlake;
	/**
     * 通过信号量来控制流量
     */
	
	//private Semaphore semaphore = new Semaphore(GlobalConfig.HANDLE_SDKS_TPS);
	
	public PacketHandler(SnowFlake snowFlake) {
		super();
		this.snowFlake = snowFlake;
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
//		if(semaphore.tryAcquire(GlobalConfig.ACQUIRE_TIMEOUTMILLIS, TimeUnit.MILLISECONDS)){
			try {
				msg.setDid(snowFlake.nextId());
				ctx.channel().writeAndFlush(msg).addListener(cf ->{ /*semaphore.release()*/;});
			} catch (Exception e) {
//				semaphore.release();
				logger.error("", e);
			}
			
//		}else{
//			msg.setDid(-1);
//			ctx.channel().writeAndFlush(msg);
//			logger.info("SdkServerHandler tryAcquire semaphore timeout, {}ms, waiting thread nums: {} availablePermit: {}",     //
//						GlobalConfig.ACQUIRE_TIMEOUTMILLIS, //
//						this.semaphore.getQueueLength(),    //
//						this.semaphore.availablePermits());   //
//			
//			throw new RuntimeException("should close channel..");
//		}
	}
	
	@Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel channel = ctx.channel();
        logger.error("SdkServerHandler channel [{}] error and will be closed", NettyUtil.parseRemoteAddr(channel), cause);
        NettyUtil.closeChannel(channel);
    }
}
